developmentor - a developer services company				  
				      Essential .NET Security
   Modules

CAS Policy

Estimated time for completion: 60 minutes


Goals of this exercise:

  • Learn how policy levels hang together
  • Get familiar with permissions
  • Learn how to figure out which permissions you need
  • Programmatically modify and deploy policy for a Windows Forms app

Overview

In this activity, we'll look at the way policy levels hang together, get familiar with the various permissions that are defined by the .NET Framework, and learn to use the documentation to figure out what permissions a particular task requires.

If you have time, you'll also get a chance to programmatically alter and deploy policy, and test your changes against a WinForms application.


part 1- Policy levels

Policy is broken into four "levels" to allow various interests to provide input. For example, the Machine policy allows the administrator of a particular machine say what code can do, while the User policy allows any user who logs on to that machine to say what code can do. But a user can't grant a permission that the administrator disallows. Remember that after each policy level is evaluated, we take the intersection of the resulting permission sets, which means that the permissions granted will be only those that the administrator AND the user agree should be granted.

steps:

  1. Run mscorcfg.msc (Start:Administrative Tools:Microsoft .NET Framework Configuration) in an administrative security context.

  2. Select the Runtime Security Policy object from the tree view, then choose the task called "Adjust Zone Security". When asked, say you want to make changes to "this computer" - this means you're adjusting the Machine security policy.

  3. You will then be allowed to adjust the security "level" for each zone. The little slider bar gives you four choices, not all of which are labeled, but for our purposes, we'll call them:

    1. Full Trust
    2. Medium Trust
    3. Low Trust
    4. No Trust

    Select the My Computer zone and drop the slider down to Medium Trust (one notch below Full Trust). Accept your changes.

  4. Verify that your change had an effect on the Machine policy level by drilling down into the code groups under the tree view (Runtime Security Policy: Machine: Code Groups: All_Code: My_Computer_Zone. Look at the text describing the My_Computer_Zone code group, and you should see some text like this: "Assemblies matching the membership condition are granted this permission set at the current policy level: LocalIntranet."

    Normally this would say Full Trust, so you've successfully altered your machine policy, reducing permissions for assemblies on the local machine.

  5. Now run that same wizard a second time (Adjust Zone Security), but this time indicate that you want to change the User policy level by selecting the radio button that says "Make changes for the current user only".

    When you look at the slider options now for the My Computer zone, do you see anything different?

  6. The Wizard is pretty smart - it's noted that the Machine policy level has already locked down permissions for this zone, so it's showing you only the changes you could make that would actually have some effect. There are only three slider options available to you here:

    1. Medium Trust
    2. Low Trust
    3. No Trust

  7. The goal of this part of the lab was just to emphasize that changes made in one policy level effectively restrict what you can do in another policy level, and that the ultimate control rests with whoever does the central administration for the enterprise.

    Exit the wizard, and then reset all policy levels back to their default state by choosing the "Reset All Policy Levels" task (this shows up in the right-hand pane when you select the Runtime Security Policy object from the tree view).


part 2- Permissions

Now it's time to familiarize yourself with the various permissions that the runtime defines. It's really important to be aware what these permissions control, and their granularity. Otherwise it's really tough to design mobile code that works well in a partially trusted environment.

steps:

  1. The best way to introduce yourself to the permissions defined by the runtime is to create your own named permission set, and use mscorcfg to poke around at the various permissions you can assign to it. So we'll do that now.

  2. Run mscorcfg.msc from a non-administrative security context.

  3. Drill down into the tree view under the User policy level, into the Permission Sets node. Create a new permission set - this should bring up a wizard that asks you for a name. Give it a name (any name you like), then press Next.

  4. Now you're presented with a list of all the permissions defined by the .NET Framework. Double click each one in turn, which will bring up a dialog box asking you to provide specific details about the permission (for example, a FileIOPermission will allow you to provide one or more paths each with different levels of access). Take your time here. Give yourself about 10-15 minutes for this step.

  5. Did you notice that each permission has two basic states - a specific list of restrictions, or an option to grant unrestricted access to that permission?

  6. Using the help engine (choose Help:Index from Visual Studio to bring it up), look up the following functions and see if you can determine from the help which permissions are needed to call them (you can paste these directly into the help index to find the documentation):

    1. File.CreateText
    2. OpenFileDialog.OpenFile
    3. Socket.Connect
    4. Thread.Suspend
    5. Environment.ExpandEnvironmentVariables
    6. EventLog.CreateEventSource

    Hint: scroll to the bottom of the docs for each function.

    At the time of this writing, one of the above listed methods does not document what permissions are required to call it.

  7. Reset all policy levels back to their default state.


part 3- Modifying policy programmatically (optional)

In this part, you'll be given a Windows Forms application that you're supposed to distribute using "zero deployment" to all students in the room. You can simulate this on your own machine or choose one person in the room to be the distribution point.

Your mission is to complete the implementation of an MSI file (Microsoft Installer) that will adjust security policy on each student's machine to allow this program to run with least privilege.

steps:

  1. First of all, whoever wants to host the application (you can all do it individually if you like) should create a virtual directory (name it "Acme") and point it to the 06_CASPolicy\AcmeExpense\web directory in your lab set.

  2. Try launching the AcmeExpense program just to see what it looks like and if it actually works when run over the Intranet. If you want to load your own version, click here: http://localhost/Acme/default.htm, otherwise surf to the web page of the person in your classroom who is acting as the deployment server.

  3. Yes, this isn't a real expense tracking app (what did you expect? ;-) Instead, we're cutting right to the meat of the problem and telling you the permissions this app would need to run if it were really built. Also listed as a sanity check are some permissions it really doesn't want to have.

    Since we've not talked about enforcement yet, don't bother looking at the source code for the app. You'll learn how the app is figuring out which permissions it has later (when we talk about permission demands). For now, just use it to gauge whether you've modified policy successfully to allow it to run.

  4. Open the AcmePermissionsInstaller solution and have a look at MyInstaller.cs. Most of the code has been provided for you (in fact, you can use this as a starting point on your own projects).

  5. Have a look at MyInstaller.Install, which is where most of the action takes place. We start by looking up the Machine policy level (for our example we'll make all of our changes here). We then create a named permission set, and this is where you need to write a little bit of code: you need to grant the permissions that AcmeExpense needs. So drag out the documentation and figure out how to do this - ask the instructor for help if you get stuck.

  6. Have a look at the construction of the code group. Note that it matches based on a strong name given to all the AcmeExpense assemblies. The code is already provided for you, all you have to do is get the public key from the AcmeExpense assembly and put it in the byte array that's defined at the bottom of the MyInstaller.cs file.

    To do this, run secutil to extract the public key from the AcmeExpense.exe assembly (which can be found in your web directory) as follows (redirect the output to a file to make your life easy):

    secutil -s AcmeExpense.exe > foo

    This tool outputs a nicely formatted (but long) byte array that gives you all 128 bytes of the public key. Copy this into your source, which should look something like this when you're done:

    byte[] acmePublicKey = new byte[]{ 0, 36, 0, 0, 4, 128, 0, 0, ...
  7. Build the solution and try running the resulting MSI file which you can find here: 06_CASPolicy\AcmeExpense\msi\before\AcmePermissions\Release\. You'll need to launch it from an administrative security context.

  8. Have a look at your machine policy and make sure a new code group and named permission set were created, and that the permissions granted do what you wanted.

  9. Try running AcmeExpense now, with the new permissions.

  10. Now think about how silly it'd be to go to all the trouble of having this secure code download mechanism if you're required to run an MSI file as an administrator (that thing can do anything it wants!). You don't want end users (who probably aren't admins anyway) running MSI files in this model. So the way to deploy these policy changes is via Active Directory group policy.

    If you have a classroom domain, and you have extra time, reset your policy levels back to their defaults and have your instructor deploy the MSI file to you via group policy. This is how security policy changes are normally deployed over an Intranet.

Solutions: